import pytest
import requests
from unittest.mock import patch

# 测试数据
TEST_ZONE = "ap-guangzhou-1"
TEST_INSTANCE_ID = "ins-rf6ogz49"
TEST_TAG_KEY = "city"
TEST_TAG_VALUE = "shenzhen"

# 模拟响应数据
MOCK_RESPONSE_SUCCESS = {
    "Response": {
        "InstanceSet": [
            {
                "InstanceId": TEST_INSTANCE_ID,
                "InstanceName": "TestInstance",
                "InstanceState": "RUNNING",
                "Placement": {"Zone": TEST_ZONE}
            }
        ],
        "TotalCount": 1,
        "RequestId": "mock-request-id"
    }
}

MOCK_RESPONSE_FILTERED = {
    "Response": {
        "InstanceSet": [],
        "TotalCount": 0,
        "RequestId": "mock-filter-request-id"
    }
}

MOCK_RESPONSE_ERROR = {
    "Response": {
        "Error": {
            "Code": "InvalidParameterValue",
            "Message": "Invalid parameter value"
        },
        "RequestId": "mock-error-request-id"
    }
}


# 测试类
class TestDescribeInstances:
    @patch('requests.post')
    def test_list_instances_success(self, mock_post):
        """测试正常查询实例列表"""
        # 设置模拟响应
        mock_post.return_value = MOCK_RESPONSE_SUCCESS

        # 构造请求参数
        params = {
            "Action": "DescribeInstances",
            "Version": "2017-03-12",
            "Region": "ap-guangzhou",
            "Filters": [{"Name": "zone", "Values": [TEST_ZONE]}]
        }

        # 发起请求
        response = requests.post("https://cvm.tencentcloudapi.com/", json=params)

        # 断言验证
        assert response == MOCK_RESPONSE_SUCCESS
        assert response["Response"]["TotalCount"] == 1
        assert response["Response"]["InstanceSet"][0]["InstanceId"] == TEST_INSTANCE_ID
        assert response["Response"]["InstanceSet"][0]["Placement"]["Zone"] == TEST_ZONE

    @patch('requests.post')
    def test_list_instances_filter_tag(self, mock_post):
        """测试标签过滤功能"""
        # 设置模拟响应
        mock_post.return_value = MOCK_RESPONSE_FILTERED

        # 构造带标签过滤的请求参数
        params = {
            "Action": "DescribeInstances",
            "Version": "2017-03-12",
            "Region": "ap-guangzhou",
            "Filters": [{"Name": f"tag:{TEST_TAG_KEY}", "Values": [TEST_TAG_VALUE]}]
        }

        # 发起请求
        response = requests.post("https://cvm.tencentcloudapi.com/", json=params)

        # 断言验证
        assert response == MOCK_RESPONSE_FILTERED
        assert response["Response"]["TotalCount"] == 0
        assert len(response["Response"]["InstanceSet"]) == 0

    @patch('requests.post')
    def test_invalid_parameters(self, mock_post):
        """测试无效参数处理"""
        # 设置模拟错误响应
        mock_post.return_value = MOCK_RESPONSE_ERROR

        # 构造无效参数请求
        params = {
            "Action": "DescribeInstances",
            "Version": "2017-03-12",
            "Region": "ap-guangzhou",
            "Filters": [{"Name": "invalid-filter", "Values": ["test"]}]
        }

        # 发起请求
        response = requests.post("https://cvm.tencentcloudapi.com/", json=params)

        # 断言验证
        assert response == MOCK_RESPONSE_ERROR
        assert response["Response"]["Error"]["Code"] == "InvalidParameterValue"

    @patch('requests.post')
    def test_pagination(self, mock_post):
        """测试分页功能"""
        # 设置模拟分页响应
        mock_post.side_effect = [
            MOCK_RESPONSE_SUCCESS,  # 第一次请求（Offset=0）
            MOCK_RESPONSE_SUCCESS  # 第二次请求（Offset=1）
        ]

        # 第一次请求（Offset=0）
        params = {
            "Action": "DescribeInstances",
            "Version": "2017-03-12",
            "Region": "ap-guangzhou",
            "Limit": 1,
            "Offset": 0
        }
        response1 = requests.post("https://cvm.tencentcloudapi.com/", json=params)

        # 第二次请求（Offset=1）
        params["Offset"] = 1
        response2 = requests.post("https://cvm.tencentcloudapi.com/", json=params)

        # 断言验证
        assert response1 == MOCK_RESPONSE_SUCCESS
        assert response1["Response"]["TotalCount"] == 1
        assert response1["Response"]["InstanceSet"][0]["InstanceId"] == TEST_INSTANCE_ID

        assert response2 == MOCK_RESPONSE_SUCCESS
        assert response2["Response"]["TotalCount"] == 1
        assert response2["Response"]["InstanceSet"][0]["InstanceId"] == TEST_INSTANCE_ID


# 运行测试
if __name__ == "__main__":
    pytest.main([__file__, "-s", "--html=report.html"])